﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using Net_framework_4.System;
using VoxelBlock.VoxelBlock3D;

namespace VoxelBlock
{
    public class BasicAlgorithm
    {
        /// <summary>
        /// 获得最大值 和 最小值
        /// </summary>
        /// <param name="positions"></param>
        /// <returns></returns>
        public static Tuple<Vector3Int, Vector3Int> GetMaxMinPosition(IEnumerable<Vector3Int> positions)
        {
            int maxX = int.MinValue;
            int maxY = int.MinValue;
            int maxZ = int.MinValue;
            int minX = int.MaxValue;
            int minY = int.MaxValue;
            int minZ = int.MaxValue;
            foreach (var item in positions)
            {
                if (item.x > maxX)
                {
                    maxX = item.x;
                }
                if (item.y > maxY)
                {
                    maxY = item.y;
                }
                if (item.z > maxZ)
                {
                    maxZ = item.z;
                }

                if (item.x < minX)
                {
                    minX = item.x;
                }
                if (item.y < minY)
                {
                    minY = item.y;
                }
                if (item.z < minZ)
                {
                    minZ = item.z;
                }
            }
            return Tuple.Create<Vector3Int, Vector3Int>(new Vector3Int(maxX, maxY, maxZ), new Vector3Int(minX, minY, minZ));

        }

        public static Tuple<Vector3Int, Vector3Int> GetMaxMinPosition(IEnumerable<SimpleVoxel> vox)
        {
            int maxX = int.MinValue;
            int maxY = int.MinValue;
            int maxZ = int.MinValue;
            int minX = int.MaxValue;
            int minY = int.MaxValue;
            int minZ = int.MaxValue;
            foreach (var voxitem in vox)
            {
                var item = voxitem.position;
                if (item.x > maxX)
                {
                    maxX = item.x;
                }
                if (item.y > maxY)
                {
                    maxY = item.y;
                }
                if (item.z > maxZ)
                {
                    maxZ = item.z;
                }

                if (item.x < minX)
                {
                    minX = item.x;
                }
                if (item.y < minY)
                {
                    minY = item.y;
                }
                if (item.z < minZ)
                {
                    minZ = item.z;
                }
            }
            return Tuple.Create<Vector3Int, Vector3Int>(new Vector3Int(maxX, maxY, maxZ), new Vector3Int(minX, minY, minZ));

        }


        public static Tuple<Vector3Int, Vector3Int> GetMaxMinPosition(IEnumerable<Voxel3D> positions)
        {
            int maxX = int.MinValue;
            int maxY = int.MinValue;
            int maxZ = int.MinValue;
            int minX = int.MaxValue;
            int minY = int.MaxValue;
            int minZ = int.MaxValue;
            foreach (var item in positions)
            {
                if (item.worldPosition.x > maxX)
                {
                    maxX = item.worldPosition.x;
                }
                if (item.worldPosition.y > maxY)
                {
                    maxY = item.worldPosition.y;
                }
                if (item.worldPosition.z > maxZ)
                {
                    maxZ = item.worldPosition.z;
                }

                if (item.worldPosition.x < minX)
                {
                    minX = item.worldPosition.x;
                }
                if (item.worldPosition.y < minY)
                {
                    minY = item.worldPosition.y;
                }
                if (item.worldPosition.z < minZ)
                {
                    minZ = item.worldPosition.z;
                }
            }
            return Tuple.Create<Vector3Int, Vector3Int>(new Vector3Int(maxX, maxY, maxZ), new Vector3Int(minX, minY, minZ));

        }

        /// <summary>
        /// 选择一片区域
        /// </summary>
        /// <param name="position">初始坐标</param>
        /// <param name="a_Condition_IsContinue">在这个条件下跳过这个坐标，输入Vector2Int:坐标，输出bool:是否跳过</param>
        /// <returns>选择的坐标</returns>
        public static Dictionary<int, Vector2Int> GetSliceBlock(Vector2Int position,
           Func<Vector2Int, bool> a_Condition_IsContinue
            )
        {
            //DateTime a =  DateTime.Now;
            Dictionary<int, Vector2Int> return_SlicesBlocks = new Dictionary<int, Vector2Int>();

            Func<List<Vector2Int>, List<Vector2Int>> Fun_a =
                (a_position_list) =>
                {
                    List<Vector2Int> return_array = new List<Vector2Int>(4);

                    foreach (var loop_item in a_position_list)
                    {
                        if (a_Condition_IsContinue(loop_item))
                        {
                            continue;
                        }

                        int var_key = loop_item.GetHashCode();

                        if (return_SlicesBlocks.ContainsKey(var_key))
                        {
                            continue;
                        }

                        return_SlicesBlocks[var_key] = loop_item;
                        return_array.Add(loop_item + new Vector2Int(0, 1));
                        return_array.Add(loop_item + new Vector2Int(0, -1));
                        return_array.Add(loop_item + new Vector2Int(1, 0));
                        return_array.Add(loop_item + new Vector2Int(-1, 0));
                    }

                    return return_array;
                };

            List<Vector2Int> var_Recursion_list = new List<Vector2Int>();
            var_Recursion_list.Add(position);

            var var_list = Fun_a(var_Recursion_list);
            while (var_list.Count > 0)
            {
                var_list = Fun_a(var_list);
            }
            //DateTime b = DateTime.Now;
            //Debug.Log(b-a);
            return return_SlicesBlocks;
        }


        struct data
        {
            public int id;
            public int x;
            public int y;
            public data(int x, int y, int id)
            {
                this.x = x;
                this.y = y;
                this.id = id;
            }
            public override int GetHashCode()
            {
                return (this.x) | (this.y << 0x0F);
            }
        }

        public static Dictionary<int, Vector2Int> GetSliceBlock2(Vector2Int position,
          Func<Vector2Int, bool> a_Condition_IsContinue
           )
        {
            //DateTime a = DateTime.Now;
            Dictionary<int, Vector2Int> return_SlicesBlocks = new Dictionary<int, Vector2Int>();

            Func<List<data>, List<data>> Fun_a =
                (a_position_list) =>
                {
                    List<data> return_array = new List<data>(1024);

                    foreach (var loop_item in a_position_list)
                    {
                        Vector2Int loop_Vector2Int = new Vector2Int(loop_item.x, loop_item.y);
                        if (a_Condition_IsContinue(loop_Vector2Int))
                        {
                            continue;
                        }

                        int var_key = loop_item.GetHashCode();

                        if (return_SlicesBlocks.ContainsKey(var_key))
                        {
                            continue;
                        }

                        //return_SlicesBlocks[var_key] = loop_Vector2Int;
                        if (loop_item.id == 1)
                        {
                            int index = 0;
                            while (true)
                            {
                                var var_Vector2Int2 = new Vector2Int(loop_item.x, loop_item.y + index);
                                var var_key2 = var_Vector2Int2.GetHashCode();
                                if (a_Condition_IsContinue(var_Vector2Int2))
                                {
                                    break;
                                }
                                if (return_SlicesBlocks.ContainsKey(var_key2))
                                {
                                    break;
                                }
                                return_SlicesBlocks[var_key2] = var_Vector2Int2;

                                return_array.Add(new data(loop_item.x - 1, loop_item.y + index, 2));
                                return_array.Add(new data(loop_item.x + 1, loop_item.y + index, 4));
                                index++;
                            }
                        }
                        else if (loop_item.id == 2)
                        {
                            int index = 0;
                            while (true)
                            {
                                var var_Vector2Int2 = new Vector2Int(loop_item.x - index, loop_item.y);
                                var var_key2 = var_Vector2Int2.GetHashCode();
                                if (a_Condition_IsContinue(var_Vector2Int2))
                                {
                                    break;
                                }
                                if (return_SlicesBlocks.ContainsKey(var_key2))
                                {
                                    break;
                                }
                                return_SlicesBlocks[var_key2] = var_Vector2Int2;

                                return_array.Add(new data(loop_item.x - index, loop_item.y - 1, 3));
                                return_array.Add(new data(loop_item.x - index, loop_item.y + 1, 1));
                                index++;
                            }
                        }
                        else if (loop_item.id == 3)
                        {
                            int index = 0;
                            while (true)
                            {
                                var var_Vector2Int2 = new Vector2Int(loop_item.x, loop_item.y - index);
                                var var_key2 = var_Vector2Int2.GetHashCode();
                                if (a_Condition_IsContinue(var_Vector2Int2))
                                {
                                    break;
                                }
                                if (return_SlicesBlocks.ContainsKey(var_key2))
                                {
                                    break;
                                }
                                return_SlicesBlocks[var_key2] = var_Vector2Int2;

                                return_array.Add(new data(loop_item.x - 1, loop_item.y - index, 2));
                                return_array.Add(new data(loop_item.x + 1, loop_item.y - index, 4));
                                index++;
                            }
                        }
                        else if (loop_item.id == 4)
                        {
                            int index = 0;
                            while (true)
                            {
                                var var_Vector2Int2 = new Vector2Int(loop_item.x + index, loop_item.y);
                                var var_key2 = var_Vector2Int2.GetHashCode();
                                if (a_Condition_IsContinue(var_Vector2Int2))
                                {
                                    break;
                                }
                                if (return_SlicesBlocks.ContainsKey(var_key2))
                                {
                                    break;
                                }
                                return_SlicesBlocks[var_key2] = var_Vector2Int2;

                                return_array.Add(new data(loop_item.x + index, loop_item.y + 1, 1));
                                return_array.Add(new data(loop_item.x + index, loop_item.y - 1, 3));
                                index++;
                            }
                        }
                        else if (loop_item.id == 0)
                        {
                            return_array.Add(new data(loop_item.x, loop_item.y + 1, 1));
                            return_array.Add(new data(loop_item.x - 1, loop_item.y, 2));
                            return_array.Add(new data(loop_item.x, loop_item.y - 1, 3));
                            return_array.Add(new data(loop_item.x + 1, loop_item.y, 4));
                        }
                    }

                    return return_array;
                };

            List<data> var_Recursion_list = new List<data>();
            var_Recursion_list.Add(new data(position.x, position.y, 1));

            var var_list = Fun_a(var_Recursion_list);
            while (var_list.Count > 0)
            {
                var_list = Fun_a(var_list);
            }
            //DateTime b = DateTime.Now;
            //Debug.Log(b - a);
            return return_SlicesBlocks;
        }


        /// <summary>
        /// 获得一个矩形
        /// </summary>
        /// <param name="a_StartPosition"></param>
        /// <param name="a_Condition_IsContinue"></param>
        /// <returns></returns>
        public static List<Vector2Int> GetRectangleBlock(Vector2Int a_StartPosition,
       Func<Vector2Int, bool> a_Condition_IsContinue
        )
        {
            List<Vector2Int> return_SlicesBlocks = new List<Vector2Int>();

            List<Vector2Int> var_UnitGhostBlocks = new List<Vector2Int>();
            var_UnitGhostBlocks.Add(a_StartPosition);

            for (int i = 1; true; i++)
            {
                var var_position = a_StartPosition + new Vector2Int(0, i);
                if (a_Condition_IsContinue(var_position))
                {
                    break;
                }
                var_UnitGhostBlocks.Add(var_position);
            }

            for (int i = -1; true; i--)
            {
                var var_position = a_StartPosition + new Vector2Int(0, i);
                if (a_Condition_IsContinue(var_position))
                {
                    break;
                }
                var_UnitGhostBlocks.Add(var_position);
            }
            return_SlicesBlocks.AddRange(var_UnitGhostBlocks);



            for (int i = 1; true; i++)
            {
                var var_UnitGhostBlocks2 = new List<Vector2Int>();
                bool var_isok = true;
                foreach (var loop_item in var_UnitGhostBlocks)
                {
                    var var_Vector2Int = loop_item + new Vector2Int(i, 0);
                    if (a_Condition_IsContinue(var_Vector2Int))
                    {
                        var_isok = false;
                        goto END;
                    }
                    var_UnitGhostBlocks2.Add(var_Vector2Int);
                }
                if (var_isok)
                {
                    return_SlicesBlocks.AddRange(var_UnitGhostBlocks2);
                }
            }
            END:

            for (int i = -1; true; i--)
            {
                var var_UnitGhostBlocks2 = new List<Vector2Int>();
                bool var_isok = true;
                foreach (var loop_item in var_UnitGhostBlocks)
                {
                    var var_Vector2Int = loop_item + new Vector2Int(i, 0);
                    if (a_Condition_IsContinue(var_Vector2Int))
                    {
                        var_isok = false;
                        goto END2;
                    }
                    var_UnitGhostBlocks2.Add(var_Vector2Int);
                }
                if (var_isok)
                {
                    return_SlicesBlocks.AddRange(var_UnitGhostBlocks2);
                }
            }
            END2:

            return return_SlicesBlocks;
        }


        /// <summary>
        /// 2维体素空间中的线性数据
        /// </summary>
        /// <param name="x1">初始x1</param>
        /// <param name="y1">初始y1</param>
        /// <param name="x2">初始x2</param>
        /// <param name="y2">初始y2</param>
        /// <returns>选择的坐标</returns>
        public static List<Vector2Int> GetLineBlock(int x1, int y1, int x2, int y2)
        {
            List<Vector2Int> V2S = new List<Vector2Int>();
            int MaxX;
            int MinX;
            int MaxY;
            int MinY;
            if (x1 < x2)
            {
                MaxX = x2;
                MinX = x1;
            }
            else
            {
                MaxX = x1;
                MinX = x2;
            }
            if (y1 < y2)
            {
                MaxY = y2;
                MinY = y1;
            }
            else
            {
                MaxY = y1;
                MinY = y2;
            }
            bool forX = true;
            if (MaxX - MinX < MaxY - MinY)
            {
                forX = false;
            }
            if (forX)
            {
                if (x1 - x2 != 0)
                {
                    float slope = (float)(y1 - y2) / (float)(x1 - x2);
                    float constant = y1 - slope * x1;
                    for (int x = MinX; x <= MaxX; x++)
                    {
                        float vy = slope * x + constant;
                        V2S.Add(new Vector2Int(x, Mathf.Round(vy)));
                    }
                }
            }
            else
            {
                if (y1 - y2 != 0)
                {
                    float slope = (float)(x1 - x2) / (float)(y1 - y2);
                    float constant = x1 - slope * y1;
                    for (int y = MinY; y <= MaxY; y++)
                    {
                        float vx = slope * y + constant;
                        V2S.Add(new Vector2Int(Mathf.Round(vx), y));
                    }
                }
            }
            return V2S;
        }

        /// <summary>
        /// 3维体素空间中的线性数据
        /// </summary>
        /// <param name="v1">起点</param>
        /// <param name="v2">终点</param>
        /// <returns></returns>
        public static List<Vector3Int> GetLineBlock3D(Vector3Int v1, Vector3Int v2)
        {
            List<Vector3Int> V3S = new List<Vector3Int>();
            if (v1 == v2)
            {
                //V3S.Add(v1);
                return V3S;
            }
            float x1 = v1.x;
            float y1 = v1.y;
            float z1 = v1.z;
            float x2 = v2.x;
            float y2 = v2.y;
            float z2 = v2.z;
            float MaxX;
            float MinX;
            float MaxY;
            float MinY;
            float MaxZ;
            float MinZ;
            if (x1 < x2)
            {
                MaxX = x2;
                MinX = x1;
            }
            else
            {
                MaxX = x1;
                MinX = x2;
            }

            if (y1 < y2)
            {
                MaxY = y2;
                MinY = y1;
            }
            else
            {
                MaxY = y1;
                MinY = y2;
            }


            if (z1 < z2)
            {
                MaxZ = z2;
                MinZ = z1;
            }
            else
            {
                MaxZ = z1;
                MinZ = z2;
            }

            int forXYZ = 1;
            if (MaxX - MinX < MaxY - MinY && MaxZ - MinZ < MaxY - MinY)
            {
                forXYZ = 2;
            }

            if (MaxX - MinX < MaxZ - MinZ && MaxY - MinY < MaxZ - MinZ)
            {
                forXYZ = 3;
            }

            if (forXYZ == 1)
            {
                if (x1 - x2 != 0)
                {
                    float slopeY = (float)(y1 - y2) / (float)(x1 - x2);
                    float constantY = y1 - slopeY * x1;

                    float slopeZ = (float)(z1 - z2) / (float)(x1 - x2);
                    float constantZ = z1 - slopeZ * x1;

                    for (float x = MinX; x <= MaxX; x++)
                    {
                        float vy = slopeY * x + constantY;
                        float vz = slopeZ * x + constantZ;
                        V3S.Add(new Vector3Int(x, Mathf.Round(vy), Mathf.Round(vz)));
                    }
                }
            }
            else if (forXYZ == 2)
            {
                if (y1 - y2 != 0)
                {
                    float slopeX = (x1 - x2) / (y1 - y2);
                    float constantX = x1 - slopeX * y1;

                    float slopeZ = (z1 - z2) / (y1 - y2);
                    float constantZ = z1 - slopeZ * y1;

                    for (float y = MinY; y <= MaxY; y++)
                    {
                        float vz = slopeZ * y + constantZ;
                        float vx = slopeX * y + constantX;
                        V3S.Add(new Vector3Int(Mathf.Round(vx), y, Mathf.Round(vz)));
                    }
                }
            }
            else if (forXYZ == 3)
            {
                if (z1 - z2 != 0)
                {
                    float slopeX = (x1 - x2) / (z1 - z2);
                    float constantX = x1 - slopeX * z1;

                    float slopeY = (y1 - y2) / (z1 - z2);
                    float constantY = y1 - slopeY * z1;

                    for (float z = MinZ; z <= MaxZ; z++)
                    {
                        float vy = slopeY * z + constantY;
                        float vx = slopeX * z + constantX;
                        V3S.Add(new Vector3Int(Mathf.Round(vx), Mathf.Round(vy), z));
                    }
                }
            }
            return V3S;
        }


        /// <summary>
        /// 3维体素空间中的线性数据
        /// </summary>
        /// <param name="v1">起点</param>
        /// <param name="v2">终点</param>
        /// <returns></returns>
        public static List<Voxel3D> GetLineBlock3D(Vector3Int v1, Vector3Int v2, int uvkey)
        {
            List<Voxel3D> V3S = new List<Voxel3D>();
            if (v1 == v2)
            {
                //V3S.Add(new Voxel3D(v1,uvkey));
                return V3S;
            }
            float x1 = v1.x;
            float y1 = v1.y;
            float z1 = v1.z;
            float x2 = v2.x;
            float y2 = v2.y;
            float z2 = v2.z;
            float MaxX;
            float MinX;
            float MaxY;
            float MinY;
            float MaxZ;
            float MinZ;
            if (x1 < x2)
            {
                MaxX = x2;
                MinX = x1;
            }
            else
            {
                MaxX = x1;
                MinX = x2;
            }

            if (y1 < y2)
            {
                MaxY = y2;
                MinY = y1;
            }
            else
            {
                MaxY = y1;
                MinY = y2;
            }


            if (z1 < z2)
            {
                MaxZ = z2;
                MinZ = z1;
            }
            else
            {
                MaxZ = z1;
                MinZ = z2;
            }

            int forXYZ = 1;
            if (MaxX - MinX < MaxY - MinY && MaxZ - MinZ < MaxY - MinY)
            {
                forXYZ = 2;
            }

            if (MaxX - MinX < MaxZ - MinZ && MaxY - MinY < MaxZ - MinZ)
            {
                forXYZ = 3;
            }

            if (forXYZ == 1)
            {
                if (x1 - x2 != 0)
                {
                    float slopeY = (float)(y1 - y2) / (float)(x1 - x2);
                    float constantY = y1 - slopeY * x1;

                    float slopeZ = (float)(z1 - z2) / (float)(x1 - x2);
                    float constantZ = z1 - slopeZ * x1;

                    for (float x = MinX; x <= MaxX; x++)
                    {
                        float vy = slopeY * x + constantY;
                        float vz = slopeZ * x + constantZ;
                        V3S.Add(new Voxel3D(
                                new Vector3Int(x, Mathf.Round(vy), Mathf.Round(vz)
                            ), uvkey));
                    }
                }
            }
            else if (forXYZ == 2)
            {
                if (y1 - y2 != 0)
                {
                    float slopeX = (x1 - x2) / (y1 - y2);
                    float constantX = x1 - slopeX * y1;

                    float slopeZ = (z1 - z2) / (y1 - y2);
                    float constantZ = z1 - slopeZ * y1;

                    for (float y = MinY; y <= MaxY; y++)
                    {
                        float vz = slopeZ * y + constantZ;
                        float vx = slopeX * y + constantX;
                        V3S.Add(new Voxel3D(new Vector3Int(Mathf.Round(vx), y, Mathf.Round(vz)), uvkey));
                    }
                }
            }
            else if (forXYZ == 3)
            {
                if (z1 - z2 != 0)
                {
                    float slopeX = (x1 - x2) / (z1 - z2);
                    float constantX = x1 - slopeX * z1;

                    float slopeY = (y1 - y2) / (z1 - z2);
                    float constantY = y1 - slopeY * z1;

                    for (float z = MinZ; z <= MaxZ; z++)
                    {
                        float vy = slopeY * z + constantY;
                        float vx = slopeX * z + constantX;
                        V3S.Add(new Voxel3D(new Vector3Int(Mathf.Round(vx), Mathf.Round(vy), z), uvkey));
                    }
                }
            }
            return V3S;
        }

        /// <summary>
        /// 根据给定的相对坐标集合 建构当前选到坐标附加的相对坐标的绝对坐标
        /// </summary>
        /// <param name="ponts">线条坐标</param>
        /// <param name="brushList">笔刷样式</param>
        /// <returns></returns>
        public static Dictionary<int, Vector2Int> GetBrushBlocks(IEnumerable<Vector2Int> ponts, IEnumerable<Vector2Int> brushList)
        {
            Dictionary<int, Vector2Int> returnBrushBlocks = new Dictionary<int, Vector2Int>();
            foreach (var pontItem in ponts)
            {
                foreach (var brushListItem in brushList)
                {
                    int key = pontItem.GetHashCode() + brushListItem.GetHashCode();
                    if (!returnBrushBlocks.ContainsKey(key))
                    {
                        returnBrushBlocks[key] = pontItem + brushListItem;
                    }
                }
            }
            return returnBrushBlocks;
        }

        /// <summary>
        /// 获得一个3D矩形方位的block
        /// </summary>
        /// <param name="positionA">起点</param>
        /// <param name="positionB">终点</param>
        /// <returns></returns>
        public static Voxel3D[] GetRectangleVoxelArray(Vector3Int positionA, Vector3Int positionB, int uvKey)
        {
            if (positionA.x > positionB.x)
            {
                int timp = positionB.x;
                positionB.x = positionA.x;
                positionA.x = timp;
            }
            if (positionA.y > positionB.y)
            {
                int timp = positionB.y;
                positionB.y = positionA.y;
                positionA.y = timp;
            }
            if (positionA.z > positionB.z)
            {
                int timp = positionB.z;
                positionB.z = positionA.z;
                positionA.z = timp;
            }
            positionB.x = positionB.x + 1;
            positionB.y = positionB.y + 1;
            positionB.z = positionB.z + 1;

            Voxel3D[] array = new Voxel3D[(positionB.x - positionA.x) * (positionB.y - positionA.y) * (positionB.z - positionA.z)];
            for (int x = positionA.x, index = 0; x < positionB.x; x++)
            {
                for (int z = positionA.z; z < positionB.z; z++)
                {
                    for (int y = positionA.y; y < positionB.y; y++, index++)
                    {
                        array[index] = new Voxel3D(new Vector3Int(x, y, z), uvKey);
                    }
                }
            }

            return array;
        }

        
        /// <summary>
        /// 获得一个椭圆空心的图案
        /// </summary>
        /// <param name="a_Pont_a"></param>
        /// <param name="a_Pont_b"></param>
        /// <returns></returns>
        public static Voxel3D[] GetEllipseBlocks(Vector3Int a_Pont_a, Vector3Int a_Pont_b, int uvKey)
        {
            var allData = GetEllipseBlocks(new Vector2Int(a_Pont_a.x, a_Pont_a.z), new Vector2Int(a_Pont_b.x, a_Pont_b.z));
            Voxel3D[] array = new Voxel3D[allData.Count];
            int index = 0;
            foreach (var item in allData.Values)
            {
                array[index] = new Voxel3D(new Vector3Int(item.x, 1, item.y),uvKey);
                index++;
            }
            return array;
        }


        /// <summary>
        /// 获得一个3D矩形方位的position
        /// </summary>
        /// <param name="positionA">起点</param>
        /// <param name="positionB">终点</param>
        /// <returns></returns>
        public static Vector3Int[] GetRectanglePointArray(Vector3Int positionA, Vector3Int positionB)
        {
            if (positionA.x > positionB.x)
            {
                int timp = positionB.x;
                positionB.x = positionA.x;
                positionA.x = timp;
            }
            if (positionA.y > positionB.y)
            {
                int timp = positionB.y;
                positionB.y = positionA.y;
                positionA.y = timp;
            }
            if (positionA.z > positionB.z)
            {
                int timp = positionB.z;
                positionB.z = positionA.z;
                positionA.z = timp;
            }
            positionB.x = positionB.x + 1;
            positionB.y = positionB.y + 1;
            positionB.z = positionB.z + 1;

            Vector3Int[] array = new Vector3Int[(positionB.x - positionA.x) * (positionB.y - positionA.y) * (positionB.z - positionA.z)];
            for (int x = positionA.x, index = 0; x < positionB.x; x++)
            {
                for (int z = positionA.z; z < positionB.z; z++)
                {
                    for (int y = positionA.y; y < positionB.y; y++, index++)
                    {
                        array[index] = new Vector3Int(x, y, z);
                    }
                }
            }

            return array;
        }

        public static Dictionary<int, Vector3Int> GetBrushBlocks3D(List<Vector3Int> ponts, IEnumerable<Vector3Int> brushList, int flowInterval)
        {
            Dictionary<int, Vector3Int> returnBrushBlocks = new Dictionary<int, Vector3Int>();


            for (int i = 0; i < ponts.Count; i += flowInterval)
            {
                foreach (var brushListItem in brushList)
                {
                    int key = ponts[i].GetHashCode() + brushListItem.GetHashCode();
                    if (!returnBrushBlocks.ContainsKey(key))
                    {
                        returnBrushBlocks[key] = ponts[i] + brushListItem;
                    }
                }
            }
            return returnBrushBlocks;
        }

        /// <summary>
        /// 获得一个矩形空心的图案
        /// </summary>
        /// <param name="a_Pont_a"></param>
        /// <param name="a_Pont_b"></param>
        /// <returns></returns>
        public static List<Vector2Int> GetRectangleBlocks(Vector2Int a_Pont_a, Vector2Int a_Pont_b)
        {
            List<Vector2Int> return_Array_Vector2Int = new List<Vector2Int>();
            int max_X, max_Y, min_X, min_Y;
            if (a_Pont_a.x > a_Pont_b.x)
            {
                max_X = a_Pont_a.x;
                min_X = a_Pont_b.x;
            }
            else
            {
                min_X = a_Pont_a.x;
                max_X = a_Pont_b.x;
            }
            if (a_Pont_a.y > a_Pont_b.y)
            {
                max_Y = a_Pont_a.y;
                min_Y = a_Pont_b.y;
            }
            else
            {
                min_Y = a_Pont_a.y;
                max_Y = a_Pont_b.y;
            }

            for (int loop_x = min_X + 1; loop_x < max_X; loop_x++)
            {
                return_Array_Vector2Int.Add(new Vector2Int(loop_x, min_Y));
                return_Array_Vector2Int.Add(new Vector2Int(loop_x, max_Y));
            }

            for (int loop_y = min_Y + 1; loop_y < max_Y; loop_y++)
            {
                return_Array_Vector2Int.Add(new Vector2Int(min_X, loop_y));
                return_Array_Vector2Int.Add(new Vector2Int(max_X, loop_y));
            }

            return_Array_Vector2Int.Add(new Vector2Int(min_X, min_Y));
            return_Array_Vector2Int.Add(new Vector2Int(max_X, max_Y));
            return_Array_Vector2Int.Add(new Vector2Int(min_X, max_Y));
            return_Array_Vector2Int.Add(new Vector2Int(max_X, min_Y));
            return return_Array_Vector2Int;
        }


        /// <summary>
        /// 获得一个椭圆空心的图案
        /// </summary>
        /// <param name="a_Pont_a"></param>
        /// <param name="a_Pont_b"></param>
        /// <returns></returns>
        public static Dictionary<int, Vector2Int> GetEllipseBlocks(Vector2Int a_Pont_a, Vector2Int a_Pont_b)
        {
            Dictionary<int, Vector2Int> return_Blocks = new Dictionary<int, Vector2Int>();
            int max_X, max_Y, min_X, min_Y;
            if (a_Pont_a.x > a_Pont_b.x)
            {
                max_X = a_Pont_a.x;
                min_X = a_Pont_b.x;
            }
            else
            {
                min_X = a_Pont_a.x;
                max_X = a_Pont_b.x;
            }
            if (a_Pont_a.y > a_Pont_b.y)
            {
                max_Y = a_Pont_a.y;
                min_Y = a_Pont_b.y;
            }
            else
            {
                min_Y = a_Pont_a.y;
                max_Y = a_Pont_b.y;
            }
            float width = ((float)(max_X - min_X)) / 2;
            float height = ((float)(max_Y - min_Y)) / 2;


            for (float loop_x = 0; loop_x < width; loop_x += 1f)
            {
                int y = (int)Mathf.Sqrt(height * height - (height * height * loop_x * loop_x) / (width * width));

                Vector2Int var_Vector2Int_1 = new Vector2Int(min_X + loop_x + width, min_Y + y + height);
                Vector2Int var_Vector2Int_2 = new Vector2Int(min_X + -loop_x + width, min_Y + y + height);
                Vector2Int var_Vector2Int_3 = new Vector2Int(min_X + loop_x + width, min_Y + -y + height);
                Vector2Int var_Vector2Int_4 = new Vector2Int(min_X + -loop_x + width, min_Y + -y + height);

                return_Blocks[var_Vector2Int_1.GetHashCode()] = var_Vector2Int_1;
                return_Blocks[var_Vector2Int_2.GetHashCode()] = var_Vector2Int_2;
                return_Blocks[var_Vector2Int_3.GetHashCode()] = var_Vector2Int_3;
                return_Blocks[var_Vector2Int_4.GetHashCode()] = var_Vector2Int_4;
            }
            for (float loop_y = 0; loop_y < height; loop_y += 1f)
            {
                int x = (int)Mathf.Sqrt(width * width - (width * width * loop_y * loop_y) / (height * height));

                Vector2Int var_Vector2Int_1 = new Vector2Int(min_X + x + width, min_Y + loop_y + height);
                Vector2Int var_Vector2Int_2 = new Vector2Int(min_X + -x + width, min_Y + loop_y + height);
                Vector2Int var_Vector2Int_3 = new Vector2Int(min_X + x + width, min_Y + -loop_y + height);
                Vector2Int var_Vector2Int_4 = new Vector2Int(min_X + -x + width, min_Y + -loop_y + height);
                if (!return_Blocks.ContainsKey(var_Vector2Int_1.GetHashCode()))
                {
                    return_Blocks[var_Vector2Int_1.GetHashCode()] = var_Vector2Int_1;
                }
                if (!return_Blocks.ContainsKey(var_Vector2Int_2.GetHashCode()))
                {
                    return_Blocks[var_Vector2Int_2.GetHashCode()] = var_Vector2Int_2;
                }
                if (!return_Blocks.ContainsKey(var_Vector2Int_3.GetHashCode()))
                {
                    return_Blocks[var_Vector2Int_3.GetHashCode()] = var_Vector2Int_3;
                }
                if (!return_Blocks.ContainsKey(var_Vector2Int_4.GetHashCode()))
                {
                    return_Blocks[var_Vector2Int_4.GetHashCode()] = var_Vector2Int_4;
                }
            }


            return return_Blocks;
        }



        /// <summary>
        /// 非递归选择一片
        /// </summary>
        /// <param name="mSlicesBlocks">返回值</param>
        /// <param name="direction">方向</param>
        /// <param name="zPosition">初始位置</param>
        /// <param name="vSliceUVxy">选择UV</param>
        /// <param name="voxBlocks">所有数据</param>
        public static void GetSliceBlock
            (Dictionary<Vector3Int, Vector3Int> mSlicesBlocks, VoxelDirection direction, 
            Vector3Int zPosition, int vSliceUVxy, IReadVoxelDictionary<Vector3Int, Voxel3D> voxBlocks,
            bool si8 = false, bool getColor = true
            )
        {
            Vector3Int[] dirVector3;
            if (si8)
            {
                dirVector3 = new Vector3Int[8];
                if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(0, 1, 0);
                    dirVector3[3] = new Vector3Int(0, -1, 0);

                    dirVector3[4] = new Vector3Int(0, -1, 1);
                    dirVector3[5] = new Vector3Int(0, 1, -1);
                    dirVector3[6] = new Vector3Int(0, -1, -1);
                    dirVector3[7] = new Vector3Int(0, 1, 1);
                }
                else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);

                    dirVector3[4] = new Vector3Int(-1, 0, 1);
                    dirVector3[5] = new Vector3Int(1, 0, -1);
                    dirVector3[6] = new Vector3Int(-1, 0, -1);
                    dirVector3[7] = new Vector3Int(1, 0, 1);
                }
                else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
                {
                    dirVector3[0] = new Vector3Int(0, 1, 0);
                    dirVector3[1] = new Vector3Int(0, -1, 0);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);

                    dirVector3[4] = new Vector3Int(-1, 1, 0);
                    dirVector3[5] = new Vector3Int(1, -1, 0);
                    dirVector3[6] = new Vector3Int(-1, -1, 0);
                    dirVector3[7] = new Vector3Int(1, 1, 0);
                }
            }
            else
            {
                dirVector3 = new Vector3Int[4];
                if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(0, 1, 0);
                    dirVector3[3] = new Vector3Int(0, -1, 0);
                }
                else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);
                }
                else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
                {
                    dirVector3[0] = new Vector3Int(0, 1, 0);
                    dirVector3[1] = new Vector3Int(0, -1, 0);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);
                }
            }

            List<Vector3Int> vSliceBlocks2 = new List<Vector3Int>();
            vSliceBlocks2.Add(zPosition);
            mSlicesBlocks[zPosition] = zPosition;

            List<Vector3Int> vSliceBlocks0;
            Vector3Int position;

            int dirVector3Length = dirVector3.Length;
            int directionContinueIndex = 0;
            switch (direction)
            {
                case VoxelDirection.Right:
                    directionContinueIndex = 0;
                    break;
                case VoxelDirection.Left:
                    directionContinueIndex = 1;
                    break;
                case VoxelDirection.Up:
                    directionContinueIndex = 2;
                    break;
                case VoxelDirection.Down:
                    directionContinueIndex = 3;
                    break;
                case VoxelDirection.Front:
                    directionContinueIndex = 4;
                    break;
                case VoxelDirection.Break:
                    directionContinueIndex = 5;
                    break;
            }
            while (vSliceBlocks2.Count > 0)
            {
                vSliceBlocks0 = new List<Vector3Int>();
                foreach (Vector3Int item in vSliceBlocks2)
                {
                    for (int i = 0; i < dirVector3Length; i++)
                    {
                        position = item + dirVector3[i];
                        if (voxBlocks.ContainsKey(position))
                        {
                            Voxel3D voxBlock = voxBlocks[position];

                            if (!voxBlock.surfaces[directionContinueIndex])
                            {
                                continue;
                            }

                            if (getColor)
                            {
                                if (voxBlock.uvKey != vSliceUVxy)
                                {
                                    continue;
                                }
                            }

                            if (!mSlicesBlocks.ContainsKey(position))
                            {
                                vSliceBlocks0.Add(position);
                                mSlicesBlocks[position] = position;
                            }
                        }
                    }
                }

                vSliceBlocks2 = vSliceBlocks0;
            }
        }

        /// <summary>
        /// 非递归选择一片
        /// </summary>
        /// <param name="mSlicesBlocks">返回值</param>
        /// <param name="direction">方向</param>
        /// <param name="zPosition">初始位置</param>
        /// <param name="vSliceUVxy">选择UV</param>
        /// <param name="voxBlocks">所有数据</param>
        public static void GetSliceBlock
      (Dictionary<Vector3Int, int> mSlicesBlocks, VoxelDirection direction,
      Vector3Int zPosition, int vSliceUVxy, IReadVoxelDictionary<Vector3Int, Voxel3D> voxBlocks,
      bool si8 = false, bool getColor = true
      )
        {
            Vector3Int[] dirVector3;
            if (si8)
            {
                dirVector3 = new Vector3Int[8];
                if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(0, 1, 0);
                    dirVector3[3] = new Vector3Int(0, -1, 0);

                    dirVector3[4] = new Vector3Int(0, -1, 1);
                    dirVector3[5] = new Vector3Int(0, 1, -1);
                    dirVector3[6] = new Vector3Int(0, -1, -1);
                    dirVector3[7] = new Vector3Int(0, 1, 1);
                }
                else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);

                    dirVector3[4] = new Vector3Int(-1, 0, 1);
                    dirVector3[5] = new Vector3Int(1, 0, -1);
                    dirVector3[6] = new Vector3Int(-1, 0, -1);
                    dirVector3[7] = new Vector3Int(1, 0, 1);
                }
                else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
                {
                    dirVector3[0] = new Vector3Int(0, 1, 0);
                    dirVector3[1] = new Vector3Int(0, -1, 0);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);

                    dirVector3[4] = new Vector3Int(-1, 1, 0);
                    dirVector3[5] = new Vector3Int(1, -1, 0);
                    dirVector3[6] = new Vector3Int(-1, -1, 0);
                    dirVector3[7] = new Vector3Int(1, 1, 0);
                }
            }
            else
            {
                dirVector3 = new Vector3Int[4];
                if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(0, 1, 0);
                    dirVector3[3] = new Vector3Int(0, -1, 0);
                }
                else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
                {
                    dirVector3[0] = new Vector3Int(0, 0, 1);
                    dirVector3[1] = new Vector3Int(0, 0, -1);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);
                }
                else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
                {
                    dirVector3[0] = new Vector3Int(0, 1, 0);
                    dirVector3[1] = new Vector3Int(0, -1, 0);
                    dirVector3[2] = new Vector3Int(1, 0, 0);
                    dirVector3[3] = new Vector3Int(-1, 0, 0);
                }
            }

            List<Vector3Int> vSliceBlocks2 = new List<Vector3Int>();
            vSliceBlocks2.Add(zPosition);
            mSlicesBlocks[zPosition] = vSliceUVxy;

            List<Vector3Int> vSliceBlocks0;
            Vector3Int position;

            int dirVector3Length = dirVector3.Length;
            int directionContinueIndex = 0;
            switch (direction)
            {
                case VoxelDirection.Right:
                    directionContinueIndex = 0;
                    break;
                case VoxelDirection.Left:
                    directionContinueIndex = 1;
                    break;
                case VoxelDirection.Up:
                    directionContinueIndex = 2;
                    break;
                case VoxelDirection.Down:
                    directionContinueIndex = 3;
                    break;
                case VoxelDirection.Front:
                    directionContinueIndex = 4;
                    break;
                case VoxelDirection.Break:
                    directionContinueIndex = 5;
                    break;
            }
            while (vSliceBlocks2.Count > 0)
            {
                vSliceBlocks0 = new List<Vector3Int>();
                foreach (Vector3Int item in vSliceBlocks2)
                {
                    for (int i = 0; i < dirVector3Length; i++)
                    {
                        position = item + dirVector3[i];
                        if (voxBlocks.ContainsKey(position))
                        {
                            Voxel3D voxBlock = voxBlocks[position];

                            if (!voxBlock.surfaces[directionContinueIndex])
                            {
                                continue;
                            }

                            if (getColor)
                            {
                                if (voxBlock.uvKey != vSliceUVxy)
                                {
                                    continue;
                                }
                            }

                            if (!mSlicesBlocks.ContainsKey(position))
                            {
                                vSliceBlocks0.Add(position);
                                mSlicesBlocks[position] = voxBlock.uvKey;
                            }
                        }
                    }
                }

                vSliceBlocks2 = vSliceBlocks0;
            }
        }


        /// <summary>
        /// 非递归选择一片,空白的
        /// </summary>
        /// <param name="mSlicesBlocks"></param>
        /// <param name="direction"></param>
        /// <param name="zPosition"></param>
        /// <param name="voxBlocks"></param>
        public static void GetSliceBlock(Dictionary<Vector3Int, Vector3Int> mSlicesBlocks, VoxelDirection direction, Vector3Int zPosition, IReadVoxelDictionary<Vector3Int, Voxel3D> voxBlocks,
            Func<Vector3Int, bool> FuncIsContinue)
        {
            Vector3Int[] dirVector3 = new Vector3Int[4];
            if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(0, 1, 0);
                dirVector3[3] = new Vector3Int(0, -1, 0);
            }
            else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }
            else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
            {
                dirVector3[0] = new Vector3Int(0, 1, 0);
                dirVector3[1] = new Vector3Int(0, -1, 0);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }

            List<Vector3Int> vSliceBlocks2 = new List<Vector3Int>();
            vSliceBlocks2.Add(zPosition);
            mSlicesBlocks[zPosition] = zPosition;

            List<Vector3Int> vSliceBlocks0;
            Vector3Int position;

            while (vSliceBlocks2.Count > 0)
            {
                vSliceBlocks0 = new List<Vector3Int>();
                foreach (Vector3Int item in vSliceBlocks2)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        position = item + dirVector3[i];
                        if (voxBlocks.ContainsKey(position))
                        {
                            continue;
                        }
                        else
                        {
                            if (FuncIsContinue(position))
                            {
                                mSlicesBlocks.Clear();
                                return;
                                //continue;
                            }
                            if (!mSlicesBlocks.ContainsKey(position))
                            {
                                vSliceBlocks0.Add(position);
                                mSlicesBlocks[position] = position;
                            }
                        }
                    }
                }

                vSliceBlocks2 = vSliceBlocks0;
            }


        }



        public static void GetSliceBlock(Dictionary<Vector3Int, Vector3Int> mSlicesBlocks, VoxelDirection direction, Vector3Int zPosition
            , int vSliceUVxy, IReadVoxelDictionary<Vector3Int, Voxel3D> voxBlocks, Dictionary<Vector3Int, Voxel3D> voxBlocks2)
        {
            Vector3Int[] dirVector3 = new Vector3Int[4];
            if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(0, 1, 0);
                dirVector3[3] = new Vector3Int(0, -1, 0);
            }
            else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }
            else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
            {
                dirVector3[0] = new Vector3Int(0, 1, 0);
                dirVector3[1] = new Vector3Int(0, -1, 0);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }

            List<Vector3Int> vSliceBlocks2 = new List<Vector3Int>();
            vSliceBlocks2.Add(zPosition);
            mSlicesBlocks[zPosition] = zPosition;

            List<Vector3Int> vSliceBlocks0;
            Vector3Int position;

            while (vSliceBlocks2.Count > 0)
            {
                vSliceBlocks0 = new List<Vector3Int>();
                foreach (Vector3Int item in vSliceBlocks2)
                {

                    for (int i = 0; i < 4; i++)
                    {
                        position = item + dirVector3[i];
                        Voxel3D voxBlock;
                        if (voxBlocks.TryGetValue(position, out voxBlock) || voxBlocks2.TryGetValue(position, out voxBlock))
                        {
                            switch (direction)
                            {
                                case VoxelDirection.Right:
                                    if (!voxBlock.surfaces[0])
                                    {
                                        continue;
                                    }
                                    break;
                                case VoxelDirection.Left:
                                    if (!voxBlock.surfaces[1])
                                    {
                                        continue;
                                    }
                                    break;
                                case VoxelDirection.Up:
                                    if (!voxBlock.surfaces[2])
                                    {
                                        continue;
                                    }
                                    break;
                                case VoxelDirection.Down:
                                    if (!voxBlock.surfaces[3])
                                    {
                                        continue;
                                    }
                                    break;
                                case VoxelDirection.Front:
                                    if (!voxBlock.surfaces[4])
                                    {
                                        continue;
                                    }
                                    break;
                                case VoxelDirection.Break:
                                    if (!voxBlock.surfaces[5])
                                    {
                                        continue;
                                    }
                                    break;
                            }


                            if (voxBlock.uvKey != vSliceUVxy)
                            {
                                continue;
                            }

                            if (!mSlicesBlocks.ContainsKey(position))
                            {
                                vSliceBlocks0.Add(position);
                                mSlicesBlocks[position] = position;
                            }
                        }
                    }
                }

                vSliceBlocks2 = vSliceBlocks0;
            }
        }
        public static void SetShadowColor(ByteTo8Bool colorShadows, Color[] colorsDatas, int startIndex, Color whiteColor)
        {
            bool[] overColorShadows = new bool[8];
            if (colorShadows[0])
            {
                overColorShadows[2] = true;
                overColorShadows[3] = true;
            }

            if (colorShadows[1])
            {
                overColorShadows[1] = true;
                overColorShadows[0] = true;
            }

            if (colorShadows[2])
            {
                overColorShadows[2] = true;
                overColorShadows[1] = true;
            }

            if (colorShadows[3])
            {
                overColorShadows[3] = true;
                overColorShadows[0] = true;
            }

            if (colorShadows[4])
            {
                overColorShadows[3] = true;
            }
            if (colorShadows[5])
            {
                overColorShadows[1] = true;
            }
            if (colorShadows[6])
            {
                overColorShadows[2] = true;
            }
            if (colorShadows[7])
            {
                overColorShadows[0] = true;
            }


            if (overColorShadows[0])
            {
                colorsDatas[startIndex + 0] = whiteColor * Color.gray;
            }
            else
            {
                colorsDatas[startIndex + 0] = whiteColor;
            }
            if (overColorShadows[1])
            {
                colorsDatas[startIndex + 1] = whiteColor * Color.gray;
            }
            else
            {
                colorsDatas[startIndex + 1] = whiteColor;
            }
            if (overColorShadows[2])
            {
                colorsDatas[startIndex + 2] = whiteColor * Color.gray;
            }
            else
            {
                colorsDatas[startIndex + 2] = whiteColor;
            }
            if (overColorShadows[3])
            {
                colorsDatas[startIndex + 3] = whiteColor * Color.gray;
            }
            else
            {
                colorsDatas[startIndex + 3] = whiteColor;
            }
        }


        public static ByteTo8Bool shaodosUV3 = new ByteTo8Bool(false);
        public static void SetShadowUV3(ByteTo8Bool colorShadows, Vector2[] uv3, int startIndex)
        {
            //shaodosUV3.SetValue(0);
            //if (colorShadows[0])
            //{
            //    shaodosUV3[2] = true;
            //    shaodosUV3[3] = true;
            //}

            //if (colorShadows[1])
            //{
            //    shaodosUV3[1] = true;
            //    shaodosUV3[0] = true;
            //}

            //if (colorShadows[2])
            //{
            //    shaodosUV3[2] = true;
            //    shaodosUV3[1] = true;
            //}

            //if (colorShadows[3])
            //{
            //    shaodosUV3[3] = true;
            //    shaodosUV3[0] = true;
            //}

            //if (colorShadows[4])
            //{
            //    shaodosUV3[3] = true;
            //}
            //if (colorShadows[5])
            //{
            //    shaodosUV3[1] = true;
            //}
            //if (colorShadows[6])
            //{
            //    shaodosUV3[2] = true;
            //}
            //if (colorShadows[7])
            //{
            //    shaodosUV3[0] = true;
            //}
            try
            {
                Array.Copy(VoxelMetadata3D.Instance.allUV3, colorShadows.GetValue() * 4, uv3, startIndex, 4);
            }
            catch (Exception)
            {

                throw;
            }
             
        }

        public static void GetSliceBlock(Dictionary<Vector3Int, Vector3Int> mSlicesBlocks, VoxelDirection direction, Vector3Int zPosition,
           Vector3Int meshSliceXYZ, int vSliceUVxy,
            IReadVoxelDictionary<Vector3Int, Voxel3D> voxBlocks, Dictionary<Vector3Int, Voxel3D> voxBlocks2)
        {
            Vector3Int[] dirVector3 = new Vector3Int[4];
            if (direction == VoxelDirection.Left || direction == VoxelDirection.Right)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(0, 1, 0);
                dirVector3[3] = new Vector3Int(0, -1, 0);
            }
            else if (direction == VoxelDirection.Up || direction == VoxelDirection.Down)
            {
                dirVector3[0] = new Vector3Int(0, 0, 1);
                dirVector3[1] = new Vector3Int(0, 0, -1);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }
            else if (direction == VoxelDirection.Front || direction == VoxelDirection.Break)
            {
                dirVector3[0] = new Vector3Int(0, 1, 0);
                dirVector3[1] = new Vector3Int(0, -1, 0);
                dirVector3[2] = new Vector3Int(1, 0, 0);
                dirVector3[3] = new Vector3Int(-1, 0, 0);
            }

            List<Vector3Int> vSliceBlocks2 = new List<Vector3Int>();
            vSliceBlocks2.Add(zPosition);
            mSlicesBlocks[zPosition] = zPosition;

            List<Vector3Int> vSliceBlocks0;
            Vector3Int position;

            while (vSliceBlocks2.Count > 0)
            {
                vSliceBlocks0 = new List<Vector3Int>();
                foreach (Vector3Int item in vSliceBlocks2)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        position = item + dirVector3[i];
                        if (voxBlocks.ContainsKey(position))
                        {

                        }
                        else if (voxBlocks2.ContainsKey(position - meshSliceXYZ) && !voxBlocks2.ContainsKey(position) && voxBlocks2[position - meshSliceXYZ].uvKey == vSliceUVxy)
                        {
                            if (position.x >= VoxelCategories.MAX_POSITION_X || position.y >= VoxelCategories.MAX_POSITION_Y || position.z >= VoxelCategories.MAX_POSITION_Z
                                ||
                                position.x <= VoxelCategories.MIN_POSITION_X || position.y <= VoxelCategories.MIN_POSITION_Y || position.z <= VoxelCategories.MIN_POSITION_Z
                                )
                            {
                                mSlicesBlocks.Clear();
                                return;
                            }
                            if (!mSlicesBlocks.ContainsKey(position))
                            {
                                vSliceBlocks0.Add(position);
                                mSlicesBlocks[position] = position;
                            }
                        }
                    }
                }

                vSliceBlocks2 = vSliceBlocks0;
            }


        }




    }
}
